Previously we seen the Overview of Objective C: Objective C : Overview
Objective-C is an extension to C
- Any C code will work in an Objective-C program.
- C data types and pointers are used in Objective-C and Cocoa programming.
- C conventions are still used.
- E.g. The main method is where program execution begins, and returns an int.
Writing Objective-C Programs
- Code is saved in .m files, e.g. “HelloWorld.m” – ‘m’ originally stood for ‘messages’.
- #import <Directory/Example.h>
- Pre-processor “import” statement means that this will only be included once. It means you don’t have to use #ifdef couples with #include.
- NSLog() is similar to printf(), but is more advanced.
- It automatically adds the end-line character.
- Must be passed an NSString.
- The NSString may take the standard formatters, including %d, and introducing %@ for an object. When the %@ is reached, the corresponding object’s description method is called, which should return an NSString.
New Data Types
- BOOL
- Stores a boolean value as “YES” or “NO”.
- Pre-dates C’s bool type by a decade.
- BOOL is just a typedef for a signed character (which uses 8 bits). Only the last bit determines the value of BOOL).
- id
- Can hold a pointer to any type of object.
- NSString
- NSString literal can be referenced using the @ shorthand. For example, “NSString message = @”Hello World!”;”
- NSArray (an enhanced array that supports objects )
- Can be traversed quickly using “for in”.
- e.g. “for (NSString * string in array) { // do something }”
Classes and Objects
- Defined using two sections, which make up a class (the interface and the implementation). These sections are normally implemented in two separate files, a .h (header) file for the interface, and a .m (source code) file for the implementation. The implementation imports the header file.
- Header files are referred to as ‘interface files’ and source code files are referred to as ‘implementation files’.
- Interface: The interface of a class is usually defined in a header file. A common convention is to name the header file after the name of the class, e.g. Ball.h would contain the interface for the class Ball.
- Implementation: The interface only declares the class interface and not the methods themselves: the actual code is written in the implementation file. Implementation (method) files normally have the file extension .m, which originally signified "messages"
- Always reference objects by using pointers.
- Sending objects messages – i.e. calling methods.
- Done using square brackets.
- E.g. “[goodBook setTitle: popularTitle];”
- Where ‘goodBook’ is an instance of a class, say, Book, setTitle is an instance method of the class Book, and ‘popularTitle’ is a variable that is of the type requested by the method setTitle.
- A method call (message send) can be made to any object. This is known as dynamic typing, and has the advantage that types can be unknown at compile time, but runs the risk of run-time errors, should a message be sent to an object that doesn’t have such a method within it. At the time of writing, my understanding of this is that exception handling must be put into place if there’s a possibility that the object won’t have the method.
- Instantiating objects: Once an Objective-C class is written, it can be instantiated. This is done by first allocating an uninitialized instance of the class (an object) and then by initializing it. An object is not fully functional until both steps have been completed.
- @class
- Is used to set up a forward reference (or forward declaration), which tells the compiler that such a class does exist, and that it’ll find out about it in the future.
- Example use: if a Class is composed of another class (or classes). Use the @class before the @interface declaration in order to let the compiler know it’ll find out more later.
- e.g “@class Brick;”
- However, if more than just the class name is being used (e.g. instance variables or methods), then that class must be imported.
Properties
- Introduced in Objective-C 2.0
- @property (parameters) <TYPE> <variable name>;
- Used in the @interface section.
- INCOMPLETE NOTES
- @synthesize
- Used in the @implementation section. This automatically creates methods as required (stated in the corresponding @property).
- Copying/Duplicating Objects
- See ‘NSCopying’ under protocols.
Objective-C Runtime:
- Creates an object for each class, known as a class object.
- This object holds pointers to the superclass, class name, class methods, and holds a long which specifies how much memory needs to be allocated to store an instance of the class.
Message/Method Dispatch System:
- Part of the Objective-C runtime code.
- A message is sent using square brackets [ and ] as follows:
- “[ boat sailFromShoreTo: america ];”
- The message is sent to the object boat, which is of type Boat, so the message goes to the class to look up the method sailFromShoreTo. If this method is not found in Boat, then the dispatch system moves to the superclass, and searches for the method there.
- If the dispatch system reaches the highest object in the hierarchy and still doesn’t find, then some serious problems may occur..
Memory Management:
- Cocoa uses reference counting (also known as retain counting).
- Every object has an integer reference count (also know as a retain count).
- When code wants to use an object it increments the retain count, and when it’s finished with it, it decrements it.
- When the retrain count reaches 0 the object is destroyed using dealloc (Objective-C will do this, don’t ever call this directly).
- Objects created using alloc, new or copy have a retrain count of 1.
- retain – increments the retain count. Returns a pointer to the object so you can chain message sends.
- release – decrements the retain count. Void method.
- retainCount – returns the retain count.
- Object ownership – when code starts using an object it should retain it, and release it when it’s finished using it.
- Mutator methods – one way of handling memory management when setting an object in composition is to – retrain the new object, then release the old, then set.
- Autorelease pool
- NSAutoreleasePool
- A collection of objects that automatically get released.
- autorelease – puts an object into an NSAutoreleasePool.
- When the pool is destroyed (using release to get to a retain count of 0), it sends release messages to all the objects in the pool.
- drain – empties the pool (releases all the objects) without destroying the pool.
- When you create an NSAutoreleasePool, it becomes the default pool all the objects go into.
Cocoa Memory Management Rules:
- A newly created object (an object created using the alloc, copy or new methods) has a retrain count of 1. The programmer is responsible for cleaning up this object.
- Retrieving an object via another mechanism – assume it has a retain count of 1 and is set to autorelease. Retain and release it if you’re going to use it for a while.
- Always balance retains and releases.
- Garbage collection
- Is possible since Objective-C 2.0. Just needs to be enabled on the compiler.
- Once enabled, all the memory management instructions are just ignored and the garbage collector is used.
- Garbage collection can’t be used on the iPhone.
Formal Protocols:
- Definition:
- A named list of methods.
- When adopting a protocol, you’re agreeing to supply these methods (and have to otherwise you’ll get a compiler error).
- Similar to Java interfaces.
- How to adopt a protocol:
- This is done in the @interface section of the class, using the following format:
- @interface className : Subclass <adoptsThisProtocol, andThisProtocol>
- The name of the protocol you wish to adopt follows within matching < and >. Multiple protocols are separated by commas.
- Protocols are inherited.
- Declaring protocols:
- @protocol <NAME>
- Start a protocol definition with this declaration.
- Must have a unique name.
- Define as many methods as necessary using the usual method declaration rules. These methods will need to be implemented by a class that adopts this protocol.
- @optional
- Objective-C 2.0
- Used before declaring methods that a class can optionally implement.
- @required
- Objective-C 2.0
- Used before declaring methods that a class has to implement.
- @end
- Ends the definition of the protocol.
Using protocols with data types:
- Protocols can be used to specify objects.
- This is achieved using the id data type, followed by the protocols that have to be implemented. For example:
- “- (void) methodName: (id<NSCopying>) objectName “.
- This method will take any object that implements the NSCopying protocol, if it doesn’t implement this protocol, the complier will give a warning.
Example/Useful Protocols:
- NSCopying
- Declares the following method:
- ” – (id) copyWithZone: (NSZone *) zone ”
- The method copy deals with the NSZone and calls this method. When using this copy method, send the copy message.
- The (NSZone *) parameter comes from old Objective-C programming. An NSZone is a location in memory that can be used for the copying (I think).
- Deep copy implementation for a class:
- Make a pointer to a class.
- Make this pointer point to [[[self class] allocWithZone: zone] init];
- The method class returns the class of the current object. If this class is extended then the copy method will still work correctly.
- The method allocWithZone allocates memory for a new object (like alloc) using an NSZone provided.
- The method init is called to initialises the object.
- A specific initialiser method can be used, passing it the values of the object-to-be-copied to initialise with.
- Or setters can be used to make the new object the same as the old one.
- The . operator can be used to access any variable. A copy method can make good, appropriate use of this operator.
- Return the pointer originally made. (This object has a retain count of 1 due to the allocWithZone method).
- For subclasses, call [super copyWithZone: zone] before doing subclass specific copying instead of calling [[self class] allocWithZone: zone] init ].
Next, we will learn about:Objective C : Headers, Interfaces, Methods
Leave Comment